package com.xli.security.thread.utils;

import cn.hutool.core.util.StrUtil;
import com.xli.security.thread.annotation.LockTask;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockManager {

    // 全局锁容器，以表名或实体名为键
    private static final ConcurrentHashMap<String, Lock> lockMap = new ConcurrentHashMap<>();

    /**
     * 获取指定表名或实体的锁
     *
     * @param key 表名或实体名
     * @return 对应的锁
     */
    private static Lock getLock(String key) {
        if (StrUtil.isBlank(key)) {
            key = "default";
        }
        // 如果锁不存在，则创建一个新的 ReentrantLock
        return lockMap.computeIfAbsent(key, k -> new ReentrantLock());
    }

    /**
     * 执行任务时对某实体或表名加锁
     *
     * @param key  表名或实体名
     * @param task 需要加锁执行的任务
     * @param <T>  任务返回值类型
     * @return 任务返回值
     * @throws Exception 如果任务执行过程中发生异常
     */
    public static <T> T executeWithLock(String key, LockTask<T> task) throws Exception {
        Lock lock = getLock(key);
        lock.lock(); // 加锁
        try {
            return task.execute();
        } finally {
            lock.unlock(); // 确保锁释放
        }
    }
}
